/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.examples.modules.breakpointview; import java.beans.*; import java.lang.reflect.*; import java.util.*; import org.openide.TopManager; import org.openide.cookies.SourceCookie; import org.openide.debugger.*; import org.openide.loaders.DataFolder; import org.openide.nodes.*; import org.openide.src.*; import org.openide.text.Line; import org.openide.util.*; // [PENDING] s/MethodElement/ConstructorElement/g later when Hanz implements public class BPViewNode extends FilterNode { private static int[] depth = new int[10]; static void depthcharge (int i) { if (depth[i]++ > 500) { StringBuffer buf = new StringBuffer ("Depth charge:"); for (int j = 0; j < depth.length; j++) { buf.append (' '); buf.append (depth[j]); } throw new RuntimeException (buf.toString ()); } } /** * @associates Object */ private final Map vals = new HashMap (); private final PropertyChangeListener debuglist = new PropertyChangeListener () { public void propertyChange (PropertyChangeEvent ev) { System.err.println ("Event on debugger: " + ev); if (ev.getPropertyName ().equals (Debugger.PROP_BREAKPOINTS)) { System.err.println ("Breakpoints fired"); // old/new value not currently fired by std debugger impl, don't even bother //refreshCount (); // Cause all props to fire changes if applicable: Iterator it = myProps.iterator (); while (it.hasNext ()) { Node.Property prop = (Node.Property) it.next (); Object old = vals.get (prop); try { Object nue = prop.getValue (); vals.put (prop, nue); if (old != null && ! Utilities.compareObjects (old, nue)) { System.err.println ("Property changed: " + prop.getName ()); firePropertyChange0 (prop.getName (), old, nue); } } catch (InvocationTargetException ite) { ite.printStackTrace (); } catch (IllegalAccessException iae) { iae.printStackTrace (); } } } } }; private void firePropertyChange0 (String name, Object old, Object nue) { firePropertyChange (name, old, nue); } private final Set myProps = new HashSet (); // Set<Node.Property> public BPViewNode () { this (repo); } public BPViewNode (Node orig) { super (orig, orig.isLeaf () ? org.openide.nodes.Children.LEAF : new BPViewChildren (orig)); depthcharge (0); if (! isInteresting (orig)) throw new IllegalArgumentException ("uninteresting node for BPView: " + orig); //refreshDisplayName (); try { Debugger d = TopManager.getDefault ().getDebugger (); if (d != null) { System.err.println ("Adding debugger listener"); d.addPropertyChangeListener (debuglist); } } catch (DebuggerNotFoundException e) { } TopManager.getDefault ().addPropertyChangeListener (new PropertyChangeListener () { public void propertyChange (PropertyChangeEvent ev) { if (ev.getPropertyName ().equals (TopManager.PROP_DEBUGGER)) { System.err.println ("Switching debugger"); Debugger old = (Debugger) ev.getOldValue (); if (old != null) old.removePropertyChangeListener (debuglist); Debugger nue = (Debugger) ev.getNewValue (); if (nue != null) nue.addPropertyChangeListener (debuglist); } } }); final MethodElement meth = (MethodElement) orig.getCookie (MethodElement.class); final ClassElement clazz = (ClassElement) orig.getCookie (ClassElement.class); if (meth != null) { myProps.add (new PropertySupport.ReadWrite ("broken", Boolean.TYPE, "Is Broken", null) { public Object getValue () { try { Debugger d = TopManager.getDefault ().getDebugger (); if (d.findBreakpoint (meth) != null) return Boolean.TRUE; else return Boolean.FALSE; } catch (DebuggerNotFoundException e) { return Boolean.FALSE; } catch (NullPointerException e) { // XXX temp workaround for bug in JavaDebugger return Boolean.FALSE; } } public void setValue (Object o) throws IllegalArgumentException { if (! (o instanceof Boolean)) throw new IllegalArgumentException (); try { Debugger d = TopManager.getDefault ().getDebugger (); if (((Boolean) o).booleanValue ()) { if (d.findBreakpoint (meth) == null) { d.createBreakpoint (meth); } } else { Breakpoint bp = d.findBreakpoint (meth); if (bp != null) bp.remove (); } } catch (DebuggerNotFoundException e) { throw new IllegalArgumentException (e.getMessage ()); } catch (NullPointerException e) { // XXX temp workaround for bug in JavaDebugger throw new IllegalArgumentException (e.toString ()); } } }); } if (clazz != null) { myProps.add (new PropertySupport.ReadOnly ("brokenLines", int[].class, "Broken Lines", null) { public Object getValue () { try { Debugger d = TopManager.getDefault ().getDebugger (); Breakpoint[] bps = d.getBreakpoints (); String myName = clazz.getName ().getFullName (); List l = new ArrayList (); for (int i = 0; i < bps.length; i++) { Breakpoint bp = bps[i]; if (bp.getClassName ().equals (myName)) { Line line = bp.getLine (); if (line != null) l.add (new Integer (line.getLineNumber ())); } } int[] toret = new int[l.size ()]; for (int i = 0; i < toret.length; i++) toret[i] = ((Integer) l.get (i)).intValue (); return toret; } catch (DebuggerNotFoundException e) { return new int[] { }; } } }); } /* myProps.add (new PropertySupport.ReadOnly ("recursiveBreaks", Integer.TYPE, "Recursively Broken", null) { public Object getValue () { return new Integer (countBreakpoints ()); } }); */ } protected void finalize () { try { Debugger d = TopManager.getDefault ().getDebugger (); if (d != null) { System.err.println ("Removing debugger listener"); d.removePropertyChangeListener (debuglist); } } catch (DebuggerNotFoundException e) { } super.finalize (); } public Node cloneNode () { System.err.println ("Cloning " + this); depthcharge (1); return new BPViewNode (getOriginal ()); } private static final String setname = Sheet.PROPERTIES; // private static final String setname = Sheet.EXPERT; // private static final String setname = "myCustomSheet"; public Node.PropertySet[] getPropertySets () { Node.PropertySet[] oldpss = getOriginal ().getPropertySets (); if (myProps.size () == 0) return oldpss; List l = new ArrayList (); boolean found = false; for (int i = 0; i < oldpss.length; i++) { final Node.PropertySet oldps = oldpss[i]; if (! found && oldps.getName ().equals (setname)) { found = true; l.add (new Node.PropertySet (setname, oldps.getDisplayName (), oldps.getShortDescription ()) { public Node.Property[] getProperties () { Node.Property[] orig = oldps.getProperties (); Node.Property[] toret = (Node.Property[]) myProps.toArray (new Node.Property[orig.length + myProps.size ()]); System.arraycopy (orig, 0, toret, myProps.size (), orig.length); return toret; } }); } else { l.add (oldps); } } if (! found) { l.add (new Node.PropertySet (setname, /* could also give real display name + tool tip here */ setname, setname) { public Node.Property[] getProperties () { return (Node.Property[]) myProps.toArray (new Node.Property[myProps.size ()]); } }); } return (Node.PropertySet[]) l.toArray (new Node.PropertySet[l.size ()]); } /* public boolean canRename () { return false; } public String getDisplayName () { depthcharge (2); String orig = getOriginal ().getDisplayName (); System.err.println ("Getting display name for " + getName () + "; orig = " + orig); int count = countBreakpoints (); return orig + " [" + (count == -1 ? "?" : "" + count) + "]"; } */ /* private int bpCache = -1; private synchronized int countBreakpoints () { depthcharge (3); if (bpCache == -1 && getOriginal ().isLeaf ()) refreshCount (); System.err.println ("countBreakpoints called on " + this + "; result = " + bpCache); return bpCache; } private synchronized void refreshCount () { depthcharge (4); int old = bpCache; bpCache = recountBreakpoints (); if (old != bpCache) { //refreshDisplayName (); // XXX does this work now?? //Node p = getParentNode (); //if (p instanceof BPViewNode) ((BPViewNode) p).refreshCount (); // XXX these can change independently: // if (getOriginal ().getCookie (ClassElement.class) != null) firePropertyChange ("brokenLines", null, null); // if (getOriginal ().getCookie (MethodElement.class) != null) firePropertyChange ("broken", null, null); firePropertyChange ("recursiveBreaks", new Integer (old), new Integer (bpCache)); } } private int recountBreakpoints () { depthcharge (5); int count = 0; Enumeration e = getChildren ().nodes (); while (e.hasMoreElements ()) { int sub = ((BPViewNode) e.nextElement ()).countBreakpoints (); if (sub == -1) return -1; else count += sub; } Node orig = getOriginal (); MethodElement meth = (MethodElement) orig.getCookie (MethodElement.class); if (meth != null) { try { Debugger d = TopManager.getDefault ().getDebugger (); if (d.findBreakpoint (meth) != null) count++; } catch (DebuggerNotFoundException dnfe1) { // Fine. } catch (NullPointerException npe) { // XXX bug in JavaDebugger } } ClassElement clazz = (ClassElement) orig.getCookie (ClassElement.class); if (clazz != null) { try { Debugger d = TopManager.getDefault ().getDebugger (); String thisName = clazz.getName ().getFullName (); Breakpoint[] bps = d.getBreakpoints (); for (int i = 0; i < bps.length; i++) { String name = bps[i].getClassName (); if (name.equals (thisName)) count++; } } catch (DebuggerNotFoundException dnfe2) { // Fine. } } return count; } */ private static Node repo = TopManager.getDefault ().getPlaces ().nodes ().repository (); static boolean isInteresting (Node n) { depthcharge (6); return n.equals (repo) || n.getCookie (DataFolder.class) != null || n.getCookie (SourceCookie.class) != null || n.getCookie (SourceElement.class) != null || n.getCookie (ClassElement.class) != null || n.getCookie (MethodElement.class) != null || // Hack--support new "category" nodes under classes, which themselves would not have an Element cookie. (n.getChildren ().getNodes ().length > 0 && n.getChildren ().getNodes ()[0].getCookie (MethodElement.class) != null); } public static void main (String[] ign) { try { Node ns[] = TopManager.getDefault ().getNodeOperation ().select ("Select a node for Breakpoint view", "Repository", repo, new NodeAcceptor () { public boolean acceptNodes (Node[] ns) { return ns.length == 1 && isInteresting (ns[0]); } }); TopManager.getDefault ().getNodeOperation ().explore (new BPViewNode (ns[0])); } catch (UserCancelException e) { } } }